import datetime

from cacheops import cached

from app.models import WxHome
from app.views import APIResponse
from jiaozi.base_view import JwtRetrieveAPIView, JwtListAPIView
from jiaozi.utils import MmFilter, get_user_id
from .serializers import *


class ProductSalesFilter(MmFilter):
    class Meta:
        model = ProductSales
        fields = {
            'product_batch__product_info__product_style_id': ['exact'],
            'product_category': ['exact'],
            'vip_level': ['exact'],
            'vip_level__level_name': ['exact', 'iexact'],
            'is_vip_only': ['exact'],
            'price_show': ['gte', 'lte']
        }


def get_current_week():
    today = datetime.date.today()
    # ywd = datetime.datetime.now().isocalendar()   # (year, week, 周几)
    week_start = today - datetime.timedelta(days=today.weekday())  # 减几天用来控制自然周的开始日期
    week_end = week_start + datetime.timedelta(days=6)
    return week_start.strftime('%Y-%m-%d'), week_end.strftime('%Y-%m-%d')


def get_user_can_buy_amount(user_id):
    from vip.models import VipSalesOrder
    from sales.models import OrderItem
    week_start, week_end = get_current_week()
    user_current_week_vip_can_buy = dict()
    has_bought_product_ids = list()
    if user_id:
        # 获取用户的 VIP 类型
        current_time = datetime.datetime.now()
        user_vips = list(VipSalesOrder.objects.filter(
            user_id=user_id,
            is_payed=True,
            vip_sales__vip_start__lte=current_time,
            vip_sales__vip_end__gte=current_time,
            amount_used__lt=12
        ).values_list(
            'vip_sales__vip_level_id', flat=True
        ).order_by(
            'price_initial'
        ).distinct())

        for vip_level in user_vips:
            user_current_week_vip_can_buy[vip_level] = 1  # 默认用户每周可以购买一次

        this_week_bought_list = list(OrderItem.objects.filter(
            product_sales_order__user_id=user_id,
            product_sales_order__datetime_created__gte=week_start,
            product_sales_order__is_show=True,
            product_sales__is_vip_only=True
        ).values(
            'pk', 'product_sales_id', 'amount', 'vip_level_id'
        ).distinct())  # 获取用户本周购买的数量

        # 如果本周已经购买过
        for this_week_bought in this_week_bought_list:
            product_sales_vip_level = this_week_bought.get('vip_level_id')
            if product_sales_vip_level:
                if product_sales_vip_level in user_current_week_vip_can_buy:
                    user_current_week_vip_can_buy[product_sales_vip_level] -= 1
            has_bought_product_ids.append(this_week_bought['product_sales_id'])
    print('get_user_can_buy_amount', user_id, user_current_week_vip_can_buy, has_bought_product_ids)
    return user_current_week_vip_can_buy, has_bought_product_ids


class ProductSalesListView(JwtListAPIView):
    """
    在售产品列表
    """
    permission_classes = ()
    serializer_class = ProductSalesSerializer
    filterset_class = ProductSalesFilter
    queryset = None
    pagination_class = None

    def get_queryset(self):
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        queryset = ProductSales.objects.filter(
            is_show=True,
            show_start__lte=current_time,
        ).order_by('order_index', 'pk')
        return queryset

    def list(self, request, *args, **kwargs):
        from vip.models import VipLevel
        user_id = get_user_id(self)
        user_current_week_vip_can_buy, has_bought_product_ids = get_user_can_buy_amount(user_id)
        response = super().list(request, *args, **kwargs)
        data = response.data
        list_data = data['data']
        res_data = dict()
        vip_name_dict = dict()
        for product_sale in list_data:

            product_sale = get_product_sale_info(product_sale)

            vip_levels = product_sale['vip_level']

            btn_str, can_buy, new_vip_levels = get_product_sale_can_buy(
                product_sale, has_bought_product_ids, vip_levels, user_current_week_vip_can_buy)

            product_sale['can_buy'] = can_buy
            product_sale['btn_str'] = btn_str
            product_sale['vip_level'] = new_vip_levels

            if vip_levels:
                for vip_level in vip_levels:
                    vip_info = model_data_from_cache(VipLevel, vip_level)
                    if vip_level not in res_data:
                        res_data[vip_level] = list()
                        vip_name_dict[vip_level] = vip_info['level_name']
                    res_data[vip_level].append(product_sale)

        res_list = list()
        for k, v in res_data.items():
            res_list.append(
                {'name': vip_name_dict.get(k), 'data': v}
            )
        data['data'] = res_list
        return response


class ProductSalesAllListView(JwtListAPIView):
    """
    在售产品列表
    """
    permission_classes = ()
    serializer_class = ProductSalesSerializer
    filterset_class = ProductSalesFilter
    queryset = None
    pagination_class = None
    search_fields = [
        'product_batch__product_info__name_cn',
        'product_batch__product_info__short_desc_cn',
    ]

    def get_queryset(self):
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        queryset = ProductSales.objects.filter(
            is_show=True,
            show_start__lte=current_time,
        ).order_by('order_index', 'pk')

        search = self.request.query_params.get('search', '')
        hot_search, created = HotSearch.objects.get_or_create(key_word=search)
        if not created:
            hot_search.count += 1
            hot_search.save()
        return queryset

    def list(self, request, *args, **kwargs):

        user_id = get_user_id(self)
        user_current_week_vip_can_buy, has_bought_product_ids = get_user_can_buy_amount(user_id)
        response = super().list(request, *args, **kwargs)
        data = response.data
        list_data = data['data']

        for product_sale in list_data:
            product_sale = get_product_sale_info(product_sale)

            vip_levels = product_sale['vip_level']

            btn_str, can_buy, new_vip_levels = get_product_sale_can_buy(
                product_sale, has_bought_product_ids, vip_levels, user_current_week_vip_can_buy)

            product_sale['can_buy'] = can_buy
            product_sale['btn_str'] = btn_str
            product_sale['vip_level'] = new_vip_levels

        return response


def get_product_sale_info(product_sale):
    product_sale['product_batch'] = model_data_from_cache(
        ProductBatch, product_sale.get('product_batch')
    )

    product_sale['product_batch']['product_info'] = model_data_from_cache(
        ProductInfo, product_sale['product_batch']['product_info']
    )

    product_style = product_sale['product_batch']['product_info']['product_style']
    if product_style:
        product_sale['product_batch']['product_info']['product_style'] = model_data_from_cache(
            ProductStyle, product_style
        )
    else:
        product_sale['product_batch']['product_info']['product_style'] = {}
    return product_sale


def get_current_time_can_buy():
    current_time = datetime.datetime.now()
    btn_str = '立即购买'
    time_can_buy = False
    weekday = current_time.weekday()
    if weekday == 1:
        if current_time.hour < 19:
            btn_str = '等待发售'
        else:
            time_can_buy = True
    elif weekday == 2:  # 周三不做限制
        time_can_buy = True
    elif weekday == 3:
        if current_time.hour > 19:
            btn_str = '售卖结束'
        else:
            time_can_buy = True
    elif weekday in {4, 5}:
        btn_str = '售卖结束'
    else:
        btn_str = '等待发售'
    return btn_str, time_can_buy


def get_btn_str_and_can_buy(vip_can_buy, amount_can_buy, product_can_buy):
    btn_str, time_can_buy = get_current_time_can_buy()
    can_buy = vip_can_buy and time_can_buy and amount_can_buy and product_can_buy
    if not time_can_buy:
        return btn_str, can_buy
    if not amount_can_buy:
        btn_str = '已售罄'
        return btn_str, can_buy
    if not vip_can_buy:
        btn_str = '不可购买'
    if not product_can_buy:
        btn_str = '已购买'
    return btn_str, can_buy


def get_product_sale_can_buy(product_sale, has_bought_product_ids,  vip_levels, user_current_week_vip_can_buy):
    from vip.models import VipLevel

    product_can_buy = True

    product_sale_id = product_sale['id']
    if product_sale_id in has_bought_product_ids:
        product_can_buy = False

    vip_can_buy = False
    new_vip_levels = list()
    if vip_levels:
        for vip_level in vip_levels:
            if vip_level in user_current_week_vip_can_buy:
                if user_current_week_vip_can_buy[vip_level] > 0:
                    vip_can_buy = True
            vip_level = model_data_from_cache(VipLevel, vip_level)
            new_vip_levels.append(vip_level)
    else:
        vip_can_buy = True

    if product_sale['amount_initial'] > product_sale['current_sales']:
        amount_can_buy = True
    else:
        amount_can_buy = False

    btn_str, can_buy = get_btn_str_and_can_buy(vip_can_buy, amount_can_buy, product_can_buy)
    return btn_str, can_buy, new_vip_levels


class ProductSalesRetrieveAPIView(JwtRetrieveAPIView):
    """
    在售产品
    """
    permission_classes = ()
    serializer_class = ProductSalesSerializer
    queryset = None
    filter_backends = ()

    def get_queryset(self):
        queryset = ProductSales.objects.all()
        return queryset

    def retrieve(self, request, *args, **kwargs):

        user_id = get_user_id(self)

        user_current_week_vip_can_buy, has_bought_product_ids = get_user_can_buy_amount(user_id)

        instance = self.get_object()
        serializer = self.get_serializer(instance)
        product_sale = serializer.data

        product_sale = get_product_sale_info(product_sale)

        product_sale['images'] = list()
        if product_sale['main_image']:
            product_sale['images'].append(product_sale['main_image'])

        vip_levels = product_sale['vip_level']

        btn_str, can_buy, new_vip_levels = get_product_sale_can_buy(
            product_sale, has_bought_product_ids,  vip_levels, user_current_week_vip_can_buy)

        product_sale['can_buy'] = can_buy
        product_sale['btn_str'] = btn_str
        product_sale['vip_level'] = new_vip_levels

        wx_home = WxHome.objects.filter(is_active=True).order_by('pk').first()
        product_sale['activity_time'] = '每周二19:00-每周四19:00'
        product_sale['charge'] = '￥0.00-30.00'
        if wx_home:
            product_sale['activity_time'] = wx_home.activity_time
            product_sale['charge'] = wx_home.charge
        return APIResponse(data=product_sale, status=200)
